package jsu.blogger.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class ObjectProcessingUtil {

    /**
     * 通过反射将对象转化为 Map 不包扩父类
     */
    public static <T> Map<String, Object> convertObjectToMap(T object) {
        Map<String, Object> resultMap = new HashMap<>();
        if (object == null) {
            return resultMap;  // 如果对象为空，返回空的 Map
        }
        // 获取对象的 Class 对象
        Class<?> clazz = object.getClass();
        // 获取类的所有字段
        Field[] fields = clazz.getDeclaredFields();
        // 遍历所有字段
        for (Field field : fields) {
            try {
                // 设置私有字段可以访问
                field.setAccessible(true);
                // 获取字段名和值
                String fieldName = field.getName();
                Object fieldValue = field.get(object);
                // 将字段名和字段值存入 Map
                resultMap.put(fieldName, fieldValue);
            } catch (IllegalAccessException e) {
                e.printStackTrace();  // 处理反射异常
            }
        }
        return resultMap;
    }

    /**
     * 提取对象的所有字段（包括父类字段，但不包括 Object 类的字段），并转化为 Map
     *
     * @param object 目标对象
     * @return 返回对象字段的映射（Map）
     */
    public static <T> Map<String, Object> extractFieldsToMap(T object) {
        Map<String, Object> objectMap = new HashMap<>();
        // 获取对象的 Class
        Class<?> clazz = object.getClass();
        // 递归获取所有字段（不包括 Object 类的字段）
        while (clazz != null && clazz != Object.class) {
            // 获取当前类的所有字段
            Field[] fields = clazz.getDeclaredFields();
            // 遍历当前类的字段
            for (Field field : fields) {
                field.setAccessible(true); // 设置访问权限
                try {
                    // 获取字段的名字和对应的值
                    String fieldName = field.getName();
                    Object fieldValue = field.get(object);
                    // 存入 Map
                    objectMap.put(fieldName, fieldValue);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();  // 如果无法访问字段，打印错误
                }
            }
            // 获取父类，继续递归处理
            clazz = clazz.getSuperclass();
        }
        return objectMap;
    }
    //包括父类 map转换成对象
    public static <T> T mapToObjectIncludeSuper(Map<Object, Object> map, Class<T> clazz) throws Exception {
        // 创建目标对象
        T object = clazz.getDeclaredConstructor().newInstance();
        // 遍历 map，将 map 中的字段值设置到对象中
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            String fieldName = (String) entry.getKey();  // 获取字段名
            Object value = entry.getValue();             // 获取字段值
            // 通过反射获取对应字段
            Field field = getField(clazz,fieldName);
            field.setAccessible(true);  // 如果字段是 private，要设置为 accessible
            // 类型检查与转换
            if (value != null) {
                Class<?> fieldType = field.getType();
                if (!fieldType.isAssignableFrom(value.getClass())) {
                    value = convertValue(value, fieldType); // 转换值的类型
                }
            }
            // 将值赋给对象的字段
            field.set(object, value);
        }
        return object;
    }
    // 递归查找字段，包括父类
    private static Field getField(Class<?> clazz, String fieldName) {
        while (clazz != null && clazz != Object.class) {
            try {
                return clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass(); // 查找父类
            }
        }
        return null; // 如果没有找到字段，返回 null
    }

    // 类型强制转换方法
    private static Object convertValue(Object value, Class<?> targetType) {
        if (targetType == Integer.class) {
            return Integer.valueOf(value.toString());
        } else if (targetType == Long.class) {
            return Long.valueOf(value.toString());
        } else if (targetType == Double.class) {
            return Double.valueOf(value.toString());
        } else if (targetType == Boolean.class) {
            return Boolean.valueOf(value.toString());
        }
        // 添加其他类型的转换
        return value; // 默认返回原值
    }
}
